package tinify

import (
	"io/ioutil"
	"net/http"
	"errors"
)

type Source struct {
	url string
	commands map[string]interface{}
}

func newSource(url string, commands map[string]interface{}) *Source {
	s := new(Source)
	s.url = url
	if commands != nil {
		s.commands = commands
	} else {
		s.commands = make(map[string]interface{})
	}

	return s
}

func FormFile(path string) (s *Source, err error) {
	buf, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, err
	}

	return FormBuffer(buf)
}

func FormBuffer(buf []byte) (s *Source, err error) {
	response, err := GetClient().Request(http.MethodPost, "/shrink", buf)
	if err != nil {
		return nil, err
	}

	return getSourceFormResponse(response), nil
}

func getSourceFormResponse(response *http.Response) (s *Source) {
	url := response.Header.Get("location")
	s = newSource(url, nil)
	return s
}

func (s *Source) ToFile(path string) error {
	result, err := s.toResult()
	if err != nil {
		return err
	}

	return result.ToFile(path)
}

func (s *Source) toResult() (r *Result, err error) {
	if len(s.url) == 0 {
		return nil, errors.New("url is empty")
	}

	response, err := GetClient().Request(http.MethodGet, s.url, s.commands)
	if err != nil {
		return nil, err
	}

	defer response.Body.Close()
	data, err := ioutil.ReadAll(response.Body)
	if err != nil {
		return nil, err
	}

	r = NewResult(response.Header, data)
	return r, nil
}